/*
 * =====================================================================================
 *
 *       Filename:  observer.cpp
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  02/12/2011 02:10:51 PM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  dp (8023), dp8023@gmail.com
 *        Company:  
 *
 * =====================================================================================
 */

#include "observer.h"

void subject::attach(observer *pobs)
{
	if (!pobs)
		return ;

	m_setobs.insert(pobs);
}

void subject::detach(observer *pobs)
{
	if (!pobs)
		return ;

	m_setobs.erase(pobs);
}

void subject::detachall()
{
	m_setobs.clear();
}

bool subject::haschanged()
{
	return m_bchanged;
}

int subject::getobservercount()
{
	return m_setobs.size();
}

void subject::setchanged()
{
	m_bchanged = true;
}

void subject::clearchanged()
{
	m_bchanged = false;
}

void subject::notify(void *parg)
{
	if (!haschanged())
		return ;

	clearchanged();

	set<observer *>::iterator itr = m_setobs.begin();
	for (; itr != m_setobs.end(); ++itr)
	{
		(*itr)->update(this, parg);
	}
}

void portal::publish(const string &strcontent)
{
	cout << "portal publish, content: " << strcontent << endl;
	setchanged();
	notify(const_cast<char *>(strcontent.c_str()));
}

void bloger::publish(const string &strcontent)
{
	cout << "bloger publish, content: " << strcontent << endl;
	setchanged();
	notify(const_cast<char *>(strcontent.c_str()));
}

void rssreader::update(subject *psub, void *parg)
{
	char *pcontent = static_cast<char *>(parg);

	if (dynamic_cast<bloger *>(psub))
	{
		cout << m_strname << " update from bloger, content: " << pcontent << endl;
	}
	else if (dynamic_cast<portal *>(psub))
	{
		cout << m_strname << " update from portal, content: " << pcontent << endl;
	}
}

void mailreader::update(subject *psub, void *parg)
{
	char *pcontent = static_cast<char *>(parg);

	if (dynamic_cast<bloger *>(psub))
	{
		cout << m_strname << " update from bloger, content: " << pcontent << endl;
	}
	else if (dynamic_cast<portal *>(psub))
	{
		cout << m_strname << " update from portal, content: " << pcontent << endl;
	}
}

